/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package ru.bfpro.cftsourceadmin;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelListener;
import javax.swing.table.*;
import javax.swing.text.Position;
import javax.swing.tree.*;
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.OracleDataSource;
import org.tmatesoft.svn.core.SVNCommitInfo;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.ISVNEditor;
import org.tmatesoft.svn.core.io.ISVNSession;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.ISVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNCommitClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
/**
 *
 * @author fbn
 */
public class frmModel extends javax.swing.JFrame {
    public String Database = "";
    public String User = "";
    public String Password = "";

    private Connection con;
    private String [] methodColumnNames = {"Наименование", 
                                            "Короткое наименование", 
                                            "Тип", 
                                            "Дата создания", 
                                            "Создал", 
                                            "Дата редактирования", 
                                            "Изменил", 
                                            "ID",
                                            "Статус"};
    /**
     * Creates new form frmModel
     */
    public frmModel() {
        initComponents();
        initRepository();
        
        try {
            do_Login();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        toolBar = new javax.swing.JToolBar();
        statusBar = new javax.swing.JToolBar();
        labelStatus = new javax.swing.JLabel();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
        labelSelected = new javax.swing.JLabel();
        filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
        labelSelectedClass = new javax.swing.JLabel();
        filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 0), new java.awt.Dimension(10, 32767));
        labelMethod_ShortName = new javax.swing.JLabel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        treeObjects = new javax.swing.JTree();
        jSplitPane2 = new javax.swing.JSplitPane();
        jScrollPane4 = new javax.swing.JScrollPane();
        tableMethods = new javax.swing.JTable();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        sourceExecute = new javax.swing.JTextArea();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        sourceValidate = new javax.swing.JTextArea();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane5 = new javax.swing.JScrollPane();
        sourcePublic = new javax.swing.JTextArea();
        jPanel4 = new javax.swing.JPanel();
        jScrollPane6 = new javax.swing.JScrollPane();
        sourcePrivate = new javax.swing.JTextArea();
        jPanel5 = new javax.swing.JPanel();
        jScrollPane7 = new javax.swing.JScrollPane();
        sourceVBScript = new javax.swing.JTextArea();
        jPanel6 = new javax.swing.JPanel();
        btnRepoCommit = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Модель схемы");

        toolBar.setFloatable(false);
        toolBar.setRollover(true);

        statusBar.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        statusBar.setFloatable(false);
        statusBar.setRollover(true);

        labelStatus.setText("Message");
        statusBar.add(labelStatus);
        statusBar.add(filler1);

        labelSelected.setText("...");
        statusBar.add(labelSelected);
        statusBar.add(filler2);

        labelSelectedClass.setText("...");
        statusBar.add(labelSelectedClass);
        statusBar.add(filler3);

        labelMethod_ShortName.setText("...");
        statusBar.add(labelMethod_ShortName);

        jSplitPane1.setDividerLocation(200);
        jSplitPane1.setResizeWeight(0.3);

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("root");
        treeObjects.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        treeObjects.setRootVisible(false);
        treeObjects.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                treeObjectsValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(treeObjects);

        jSplitPane1.setLeftComponent(jScrollPane1);

        jSplitPane2.setDividerLocation(300);
        jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane2.setResizeWeight(0.5);

        tableMethods.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Наименование", "Короткое наименовани", "Тип", "Дата создания", "Создал", "Дата редактирования", "Изменил", "ID", "Статус"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
            };
            boolean[] canEdit = new boolean [] {
                false, false, false, false, false, false, false, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        tableMethods.setRowHeight(18);
        tableMethods.getSelectionModel().addListSelectionListener(new MethodSelection());
        jScrollPane4.setViewportView(tableMethods);

        jSplitPane2.setLeftComponent(jScrollPane4);

        sourceExecute.setEditable(false);
        sourceExecute.setBackground(new java.awt.Color(0, 0, 0));
        sourceExecute.setColumns(20);
        sourceExecute.setFont(new java.awt.Font("Lucida Console", 0, 12)); // NOI18N
        sourceExecute.setForeground(new java.awt.Color(51, 255, 51));
        sourceExecute.setRows(5);
        jScrollPane3.setViewportView(sourceExecute);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 685, Short.MAX_VALUE)
            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 227, Short.MAX_VALUE)
            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Код: Тело", jPanel2);

        sourceValidate.setEditable(false);
        sourceValidate.setBackground(new java.awt.Color(204, 204, 204));
        sourceValidate.setColumns(20);
        sourceValidate.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
        sourceValidate.setRows(5);
        jScrollPane2.setViewportView(sourceValidate);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Код: Валидатор", jPanel1);

        sourcePublic.setEditable(false);
        sourcePublic.setBackground(new java.awt.Color(204, 204, 204));
        sourcePublic.setColumns(20);
        sourcePublic.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
        sourcePublic.setRows(5);
        jScrollPane5.setViewportView(sourcePublic);

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Код: Глобальное описание", jPanel3);

        sourcePrivate.setEditable(false);
        sourcePrivate.setBackground(new java.awt.Color(102, 102, 102));
        sourcePrivate.setColumns(20);
        sourcePrivate.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
        sourcePrivate.setForeground(new java.awt.Color(255, 255, 0));
        sourcePrivate.setRows(5);
        jScrollPane6.setViewportView(sourcePrivate);

        javax.swing.GroupLayout jPanel4Layout = new javax.swing.GroupLayout(jPanel4);
        jPanel4.setLayout(jPanel4Layout);
        jPanel4Layout.setHorizontalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane6, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
        );
        jPanel4Layout.setVerticalGroup(
            jPanel4Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane6, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Код: Локальное описание", jPanel4);

        sourceVBScript.setEditable(false);
        sourceVBScript.setBackground(new java.awt.Color(204, 204, 204));
        sourceVBScript.setColumns(20);
        sourceVBScript.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
        sourceVBScript.setRows(5);
        jScrollPane7.setViewportView(sourceVBScript);

        javax.swing.GroupLayout jPanel5Layout = new javax.swing.GroupLayout(jPanel5);
        jPanel5.setLayout(jPanel5Layout);
        jPanel5Layout.setHorizontalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane7, javax.swing.GroupLayout.DEFAULT_SIZE, 685, Short.MAX_VALUE)
        );
        jPanel5Layout.setVerticalGroup(
            jPanel5Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane7, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)
        );

        jTabbedPane1.addTab("Код: Клиент-скрипт", jPanel5);

        btnRepoCommit.setText("Commit");
        btnRepoCommit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRepoCommitActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel6Layout = new javax.swing.GroupLayout(jPanel6);
        jPanel6.setLayout(jPanel6Layout);
        jPanel6Layout.setHorizontalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnRepoCommit)
                .addContainerGap(608, Short.MAX_VALUE))
        );
        jPanel6Layout.setVerticalGroup(
            jPanel6Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel6Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnRepoCommit)
                .addContainerGap(193, Short.MAX_VALUE))
        );

        jTabbedPane1.addTab("Репозиторий", jPanel6);

        jSplitPane2.setBottomComponent(jTabbedPane1);

        jSplitPane1.setRightComponent(jSplitPane2);

        jMenu1.setText("Управление");

        jMenuItem1.setText("Соединение с БД");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem1);

        jMenuItem2.setText("Настройка ...");
        jMenu1.add(jMenuItem2);

        jMenuItem3.setText("Выход");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        jMenu1.add(jMenuItem3);

        jMenuBar1.add(jMenu1);

        jMenu2.setText("Репозиторий");
        jMenuBar1.add(jMenu2);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(toolBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(statusBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 898, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(toolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 415, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    private void treeObjectsValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_treeObjectsValueChanged
        labelSelected.setText("Current selection: " + evt.getPath().getLastPathComponent().toString());
        try {
            getClassInfo(evt.getNewLeadSelectionPath());
        } catch (SQLException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_treeObjectsValueChanged

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        try {
            do_Login();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        dispose();
    }//GEN-LAST:event_jMenuItem3ActionPerformed

    private void btnRepoCommitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRepoCommitActionPerformed
        if (tableMethods.getRowCount()==0) return;
        if (tableMethods.getSelectedRowCount()==0) return;

        Object[] selPath = treeObjects.getSelectionPath().getPath();
        String repPath;
        if (selPath.length < 3) return; 
        
        String logMessage = treeObjects.getSelectionPath().toString();
        try {
            // Формируем путь 
            repPath = selPath[2].toString();
            for (int i = 2; i < selPath.length; i++) {
                if (i > 2) repPath = repPath + "/" + selPath[i].toString();
            }
            // Добавляем каталог с объектом модели
            repPath = repPath + "/" + tableMethods.getValueAt(tableMethods.getSelectedRows()[0],1).toString() + ".method";
            // Для представлений отдельно

            // Сохранить файлы 
            // Создаем временную рабочую копию каталога
            CFTRepository.doCheckout(repPath,logMessage);
            // Сохраняем в репозиторий
            CFTRepository.doCommit(repPath, "Придумать комментарии к комиту");
        } catch (IOException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SVNException ex) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }//GEN-LAST:event_btnRepoCommitActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(frmModel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(frmModel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(frmModel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(frmModel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new frmModel().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnRepoCommit;
    private javax.swing.Box.Filler filler1;
    private javax.swing.Box.Filler filler2;
    private javax.swing.Box.Filler filler3;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JScrollPane jScrollPane6;
    private javax.swing.JScrollPane jScrollPane7;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JSplitPane jSplitPane2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JLabel labelMethod_ShortName;
    private javax.swing.JLabel labelSelected;
    private javax.swing.JLabel labelSelectedClass;
    private javax.swing.JLabel labelStatus;
    private javax.swing.JTextArea sourceExecute;
    private javax.swing.JTextArea sourcePrivate;
    private javax.swing.JTextArea sourcePublic;
    private javax.swing.JTextArea sourceVBScript;
    private javax.swing.JTextArea sourceValidate;
    private javax.swing.JToolBar statusBar;
    private javax.swing.JTable tableMethods;
    private javax.swing.JToolBar toolBar;
    private javax.swing.JTree treeObjects;
    // End of variables declaration//GEN-END:variables

    private void do_Login() throws ClassNotFoundException, SQLException {
        CftSourceAdmin.Database = "";
        CftSourceAdmin.User = "";
        CftSourceAdmin.Password = "";
        frmLogin login = new frmLogin(this, true);
        login.setVisible(true);
        
        if (CftSourceAdmin.Database.isEmpty()==false && CftSourceAdmin.User.isEmpty()==false) {
            // Нужен файл конфигурации с каталогом хранения TNS
            System.setProperty("oracle.net.tns_admin", "C:\\oracle\\product\\10.2.0\\client_1\\NETWORK\\ADMIN");
            OracleDataSource ods = new OracleDataSource();
            ods.setTNSEntryName(CftSourceAdmin.Database);
            ods.setUser(CftSourceAdmin.User);
            ods.setPassword(CftSourceAdmin.Password);
            ods.setDriverType("thin");
            try {
                con = ods.getConnection();
                labelStatus.setText(CftSourceAdmin.User+"@"+CftSourceAdmin.Database);
                /**
                 * Вот так работает
                Class.forName("oracle.jdbc.driver.OracleDriver");
                Connection con = DriverManager.getConnection("jdbc:oracle:thin:@10.48.40.2:1524/copy", CftSourceAdmin.User.toUpperCase(), CftSourceAdmin.Password.toUpperCase());
                */
                System.out.println("Connected !");
                
                // Получим список классов
                String sql = "select c.id, c.name, c.parent_id, c.base_class_id, c.agregate, c.entity_id, c.kernel, c.autonomous , c.temp_type " +
                                "from IBS.classes c connect by prior c.id = c.parent_id " +
                                "start with c.parent_id is null";
                Statement stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery(sql);
                DefaultMutableTreeNode rootNode; 
                TreePath parentPath;
                DefaultMutableTreeNode parentNode;
                DefaultTreeModel treeModel = (DefaultTreeModel)treeObjects.getModel();
                TreeNode[] nodes;
                TreePath path;
                
                rootNode = (DefaultMutableTreeNode)treeModel.getRoot();
                //
                DefaultMutableTreeNode treeNode_Base = new DefaultMutableTreeNode("Базовые понятия");
                treeModel.insertNodeInto(treeNode_Base, rootNode, rootNode.getChildCount());
                treeModel.nodeChanged(rootNode);

                //nodes = treeModel.getPathToRoot(treeNode_Base);
                //path = new TreePath(nodes);
                //treeObjects.scrollPathToVisible(path);
                
                //
                DefaultMutableTreeNode treeNode_Type = new DefaultMutableTreeNode("Типы данных");
                treeModel.insertNodeInto(treeNode_Type, rootNode, rootNode.getChildCount());
                treeModel.nodeChanged(rootNode);
                DefaultMutableTreeNode treeNode_Type_Ole = new DefaultMutableTreeNode("OLE объекты");
                DefaultMutableTreeNode treeNode_Type_Variant = new DefaultMutableTreeNode("Варианты");                        
                DefaultMutableTreeNode treeNode_Type_Table = new DefaultMutableTreeNode("Вложенные массивы");
                DefaultMutableTreeNode treeNode_Type_Date = new DefaultMutableTreeNode("Даты");
                DefaultMutableTreeNode treeNode_Type_Boolean = new DefaultMutableTreeNode("Логические");
                DefaultMutableTreeNode treeNode_Type_Collection = new DefaultMutableTreeNode("Массивы");
                DefaultMutableTreeNode treeNode_Type_Dict = new DefaultMutableTreeNode("Справочники");
                DefaultMutableTreeNode treeNode_Type_Reference = new DefaultMutableTreeNode("Ссылки");
                DefaultMutableTreeNode treeNode_Type_String = new DefaultMutableTreeNode("Строки");
                DefaultMutableTreeNode treeNode_Type_Structure = new DefaultMutableTreeNode("Структуры");
                DefaultMutableTreeNode treeNode_Type_Memo = new DefaultMutableTreeNode("Текстовые");
                DefaultMutableTreeNode treeNode_Type_Number = new DefaultMutableTreeNode("Числа");
                treeModel.insertNodeInto(treeNode_Type_Ole, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Variant, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Table, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Date, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Boolean, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Collection, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Dict, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Reference, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_String, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Structure, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Memo, treeNode_Type, treeNode_Type.getChildCount());
                treeModel.insertNodeInto(treeNode_Type_Number, treeNode_Type, treeNode_Type.getChildCount());
                //nodes = treeModel.getPathToRoot(treeNode_Type);
                //path = new TreePath(nodes);
                //treeObjects.scrollPathToVisible(path);
                
                //
                DefaultMutableTreeNode treeNode_Meta = new DefaultMutableTreeNode("Метаданные");
                treeModel.insertNodeInto(treeNode_Meta, rootNode, rootNode.getChildCount());
                treeModel.nodeChanged(rootNode);
                
                nodes = treeModel.getPathToRoot(treeNode_Meta);
                path = new TreePath(nodes);
                treeObjects.scrollPathToVisible(path);
                            
                String entity_id;
                
                int nodeIndex = 0;
                while (rs.next()) {
                    entity_id = rs.getString("entity_id");
                    DefaultMutableTreeNode node = new DefaultMutableTreeNode(rs.getString(1));
                    if (rs.getString("parent_id") == null) {
                        // Проверка ENTITY_ID
                        // Базовые понятия
                        if ("ACCOUNT".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("DOCUMENT".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("CLIENT".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("PLAN".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("FINTOOL".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("CARD".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("SYSTEM".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("USER".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("MON".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("PRODUCT".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } else if ("CATALOG_APP".equals(entity_id)) {
                            treeModel.insertNodeInto(node, treeNode_Base, treeNode_Base.getChildCount());                            
                        } // Типы данных
                            else if ("TYPE".equals(entity_id) && !"1".equals(rs.getString("kernel"))) {
                                if ("OLE".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Ole, treeNode_Type_Ole.getChildCount());
                                } else if ("STRUCTURE".equals(rs.getString("base_class_id"))) {
                                    if ("VARIANT".equals(rs.getString("agregate"))) {
                                        treeModel.insertNodeInto(node, treeNode_Type_Variant, treeNode_Type_Variant.getChildCount());
                                    } else {
                                        if ("1".equals(rs.getString("autonomous"))) {
                                            treeModel.insertNodeInto(node, treeNode_Type_Dict, treeNode_Type_Dict.getChildCount());
                                        } else {
                                            treeModel.insertNodeInto(node, treeNode_Type_Structure, treeNode_Type_Structure.getChildCount());
                                        }
                                    }
                                } else if ("TABLE".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Table, treeNode_Type_Table.getChildCount());
                                } else if ("DATE".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Date, treeNode_Type_Date.getChildCount());
                                } else if ("BOOLEAN".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Boolean, treeNode_Type_Boolean.getChildCount());
                                } else if ("COLLECTION".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Collection, treeNode_Type_Collection.getChildCount());
                                } else if ("REFERENCE".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Reference, treeNode_Type_Reference.getChildCount());
                                } else if ("STRING".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_String, treeNode_Type_String.getChildCount());
                                } else if ("MEMO".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Memo, treeNode_Type_Memo.getChildCount());
                                } else if ("NUMBER".equals(rs.getString("base_class_id"))) {
                                    treeModel.insertNodeInto(node, treeNode_Type_Number, treeNode_Type_Number.getChildCount());
                                } else {
                                    treeModel.insertNodeInto(node, treeNode_Type, treeNode_Type.getChildCount());
                                }
                        } // Метаданные
                            else if ("1".equals(rs.getString("kernel"))) {
                            treeModel.insertNodeInto(node, treeNode_Meta, treeNode_Meta.getChildCount());                            
                        } else {
                            treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
                        }
                        treeModel.nodeChanged(rootNode);
                    } else {
                        boolean is = false;
                        parentPath = treeObjects.getNextMatch(rs.getString("parent_id"), 0, Position.Bias.Forward);
                        nodeIndex = treeObjects.getRowForPath(parentPath);
                        while (is==false) {
                            if (parentPath.getLastPathComponent().toString().compareTo(rs.getString("parent_id"))==0) {
                                is = true;
                            } else {
                                parentPath = treeObjects.getNextMatch(rs.getString("parent_id"), nodeIndex+1, Position.Bias.Forward);
                                nodeIndex = treeObjects.getRowForPath(parentPath);
                            }
                            if (parentPath == null) break;
                        }
                        if (parentPath != null) {
                            parentNode = (DefaultMutableTreeNode)parentPath.getLastPathComponent();
                            treeModel.insertNodeInto(node, parentNode, parentNode.getChildCount());
                            treeModel.nodeChanged(parentNode);
                        }
                    }
                    nodes = treeModel.getPathToRoot(node);
                    path = new TreePath(nodes);
                    treeObjects.scrollPathToVisible(path);
                }
                
                // con.prepareStatement
            } catch (SQLException ex) {
                labelStatus.setText(ex.getMessage());
            }
        } else {
            labelStatus.setText("Нет подключения");
        }
                
        
    }

    private void getClassInfo(TreePath path) throws SQLException {
        Statement stmt;
        ResultSet rsClass;
        
        String classID = path.getLastPathComponent().toString();
        String className = " ";
        String sql = "select * from IBS.classes where ID = '" + classID + "'";

        stmt = con.createStatement();
        rsClass = stmt.executeQuery(sql);
        
        while (rsClass.next()) {
            className = rsClass.getString("name");
        }
        if (rsClass.getFetchSize() > 0) {
            getClassMethods(classID);
        }
        labelSelectedClass.setText(className);
    }
    
    private void getClassMethods(String classID) throws SQLException {
        Statement stmt;
        ResultSet rsMethods;
        stmt = con.createStatement();
        String sql = "SELECT m.*, IBS.method.get_obj_status(m.PACKAGE_NAME,'PACKAGE BODY') OBJ_STATUS " + 
                "FROM IBS.METHODS m WHERE m.CLASS_ID='"+classID+"' ORDER BY SHORT_NAME";
        rsMethods = stmt.executeQuery(sql);
        Vector rows = new Vector();
        while (rsMethods.next()) {
            Vector row = new Vector();
            row.addElement(rsMethods.getString("name"));
            row.addElement(rsMethods.getString("short_name"));
            row.addElement(rsMethods.getString("flags"));
            row.addElement(rsMethods.getString("created"));
            row.addElement(rsMethods.getString("user_created"));
            row.addElement(rsMethods.getString("modified"));
            row.addElement(rsMethods.getString("user_modified"));
            row.addElement(rsMethods.getString("ID"));
            row.addElement(rsMethods.getString("obj_status"));
            rows.addElement(row);
        }
        TableModel model = new MethodsTableModel(rows);
        tableMethods.setModel(model);
    }

    private void getMethodSource(String methodID) throws SQLException {
        sourceExecute.setText("");
        sourceValidate.setText("");
        sourceVBScript.setText("");
        sourcePublic.setText("");
        sourcePrivate.setText("");
        Statement stmt;
        ResultSet rsSource;
        stmt = con.createStatement();
        String sql = "select * from ibs.sources where \"NAME\" = '"+methodID+"' ORDER BY TYPE,LINE";
        rsSource = stmt.executeQuery(sql);
        while (rsSource.next()) {
            String lineText = rsSource.getString("text");
            if (lineText==null) {
                lineText = "\n";
            } else {
                lineText = lineText + "\n";
            }
            switch (rsSource.getString("type")) {
                case "EXECUTE": sourceExecute.append(lineText); 
                                break;
                case "VALIDATE": sourceValidate.append(lineText); 
                                break; 
                case "VBSCRIPT": sourceVBScript.append(lineText); 
                                break;
                case "PUBLIC" : sourcePublic.append(lineText); 
                                break; 
                case "PRIVATE": sourcePrivate.append(lineText); 
                                break;
                default: break;
            }
        }
        // 
        CFTMethod.SourceExecute = sourceExecute.getText();
        CFTMethod.SourceValidate = sourceValidate.getText();
        CFTMethod.SourceVBScript = sourceVBScript.getText();
        CFTMethod.SourcePublic = sourcePublic.getText();
        CFTMethod.SourcePrivate = sourcePrivate.getText();
    }

    /**
     * Инициализация репозитория
     */
    private void initRepository() {
        try {
            // Register factory
            FSRepositoryFactory.setup();
            // Create driver to repository
            SVNURL url = SVNURL.parseURIEncoded("file:///C:\\dev_repo\\cft");
            // file:///C:/dev_repo/cft
            CFTRepository.repo = FSRepositoryFactory.create(url, null);
            System.out.println("Repository Root: " + CFTRepository.repo.getRepositoryRoot( true ) );
            System.out.println("Repository UUID: " + CFTRepository.repo.getRepositoryUUID( true ) );
            long latestRevision = CFTRepository.repo.getLatestRevision();
            System.out.println("Repository latest revision: " + latestRevision);
            
            CFTRepository.doInit();
        } catch (Exception e) {
            Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, e);
        }
    }
    
    private class MethodSelection implements ListSelectionListener {

        public MethodSelection() {
        }

        @Override
        public void valueChanged(ListSelectionEvent e) {
            CFTMethod.empty();
            if (tableMethods.getRowCount()==0) return;
            if (tableMethods.getSelectedRowCount()==0) return;
            try {
                String ShortName = tableMethods.getValueAt(tableMethods.getSelectedRows()[0],1).toString();
                String ID = tableMethods.getValueAt(tableMethods.getSelectedRows()[0],7).toString();
                CFTMethod.ID = ID;
                CFTMethod.Name = tableMethods.getValueAt(tableMethods.getSelectedRows()[0],0).toString();
                CFTMethod.ShortName = ShortName;
                labelMethod_ShortName.setText(ShortName);
                getMethodSource(ID);
            } catch (SQLException ex) {
                Logger.getLogger(frmModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public class MethodsTableModel extends AbstractTableModel {
        private Vector rows;
        
        public MethodsTableModel(Vector rows) {
            this.rows = rows;
        }
        
        @Override
        public int getRowCount() {
            return rows.size();
        }

        @Override
        public int getColumnCount() {
            return methodColumnNames.length;
        }

        public String getColumnName(int columnIndex) {
            return methodColumnNames[columnIndex].toString();
        }
        
        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Vector row;
            row = (Vector)rows.get(rowIndex);
            return row.get(columnIndex);
        }
        
    }
}
